import hashlib
import time
from typing import Optional, List
from decimal import Decimal
from fastapi import APIRouter, HTTPException, Form
from pydantic import BaseModel, Field, validator
from app.sql.mysql_main import main_opera as read_query

router = APIRouter(
    prefix="/openapi2",
    tags=["wangdian_api"],
    responses={404: {"description": "Not found"}}
)

# 订单项模型 (order_list)
class OrderItem(BaseModel):
    oid: str = Field(..., max_length=40, description="子订单编号")
    num: Decimal = Field(..., description="货品数量")
    price: Decimal = Field(..., description="单价")
    status: int = Field(..., description="平台子订单状态")
    refund_status: int = Field(..., description="退款状态")
    goods_id: str = Field(..., max_length=40, description="平台货品ID")
    spec_id: Optional[str] = Field(None, max_length=40, description="平台规格ID")
    goods_no: Optional[str] = Field(None, max_length=40, description="货品编码")
    spec_no: str = Field(..., max_length=40, description="规格编码")
    goods_name: str = Field(..., max_length=255, description="货品名称")
    spec_name: Optional[str] = Field(None, max_length=100, description="规格名称")
    adjust_amount: Decimal = Field(..., description="调整金额")
    discount: Decimal = Field(..., description="优惠")
    share_discount: Decimal = Field(..., description="分摊优惠")
    commission: Optional[Decimal] = Field(Decimal('0'), description="佣金")
    remark: Optional[str] = Field(None, max_length=1024, description="备注")
    cid: Optional[str] = Field(None, max_length=40, description="类目")

# 订单主体模型 (trade_list)
class TradeItem(BaseModel):
    tid: str = Field(..., max_length=40, description="原始单号")
    trade_status: int = Field(..., description="平台状态")
    pay_status: Optional[int] = Field(None, description="支付状态")
    delivery_term: int = Field(..., description="发货条件")
    trade_time: Optional[str] = Field(None, description="下单时间")
    pay_time: str = Field(..., description="支付时间")
    fenxiao_type: Optional[int] = Field(None, description="分销类别")
    purchase_id: Optional[str] = Field(None, max_length=40, description="采购单ID")
    fenxiao_nick: Optional[str] = Field(None, max_length=40, description="分销商")
    buyer_nick: str = Field(..., max_length=100, description="客户网名")
    buyer_email: Optional[str] = Field(None, max_length=60, description="买家email")
    pay_id: Optional[str] = Field(None, max_length=40, description="支付单号")
    pay_account: Optional[str] = Field(None, max_length=128, description="支付账号")
    pay_method: Optional[int] = Field(1, description="支付方式")
    receiver_name: str = Field(..., max_length=40, description="收件人")
    receiver_province: str = Field(..., max_length=40, description="省份")
    receiver_city: str = Field(..., max_length=40, description="城市")
    receiver_district: str = Field(..., max_length=40, description="区县")
    receiver_address: str = Field(..., max_length=256, description="地址详情")
    receiver_mobile: str = Field(..., max_length=40, description="手机")
    receiver_telno: Optional[str] = Field(None, max_length=40, description="电话")
    receiver_zip: Optional[str] = Field(None, max_length=20, description="邮编")
    logistics_type: Optional[int] = Field(-1, description="物流方式")
    invoice_kind: Optional[int] = Field(0, description="发票类别")
    invoice_title: Optional[str] = Field(None, max_length=255, description="发票抬头")
    invoice_content: Optional[str] = Field(None, max_length=255, description="发票内容")
    remark_flag: Optional[int] = Field(0, description="客户备注标旗")
    buyer_message: Optional[str] = Field(None, max_length=1024, description="买家备注")
    seller_memo: Optional[str] = Field(None, max_length=1024, description="客服备注")
    seller_flag: Optional[int] = Field(0, description="标旗")
    post_amount: Decimal = Field(..., description="邮费")
    cod_amount: Decimal = Field(..., description="货到付款金额")
    ext_cod_fee: Decimal = Field(..., description="货到付款买家费用")
    other_amount: Decimal = Field(..., description="其它收费")
    paid: Decimal = Field(..., description="已付")
    id_card_type: Optional[int] = Field(0, description="证件类型")
    id_card: Optional[str] = Field(None, max_length=40, description="证件号码")
    is_auto_wms: Optional[int] = Field(0, description="自动流转模式")
    wms_type: Optional[int] = Field(None, description="仓库类型")
    warehouse_no: Optional[str] = Field(None, max_length=40, description="仓库编号")
    order_list: List[OrderItem] = Field(..., description="订单货品明细节点")

# 完整的API请求模型
class TradePushRequest(BaseModel):
    # 公共请求参数
    sid: str = Field(..., description="卖家账号")
    appkey: str = Field(..., description="接口账号")
    timestamp: int = Field(..., description="时间戳")
    sign: str = Field(..., description="签名")
    
    # 业务请求参数
    shop_no: str = Field(..., max_length=20, description="店铺编号")
    switch: Optional[int] = Field(1, description="模式")
    trade_list: List[TradeItem] = Field(..., description="订单列表节点")

def verify_signature(params: dict, app_secret: str) -> bool:
    """验证签名"""
    try:
        # 移除sign参数
        sign = params.pop('sign', '')
        
        # 按key排序并拼接
        sorted_params = sorted(params.items())
        query_string = '&'.join([f'{k}={v}' for k, v in sorted_params if v is not None])
        
        # 拼接app_secret
        sign_string = f"{app_secret}{query_string}{app_secret}"
        
        # MD5加密并转大写
        calculated_sign = hashlib.md5(sign_string.encode('utf-8')).hexdigest().upper()
        
        return calculated_sign == sign.upper()
    except Exception:
        return False

@router.post("/trade_push.php")
async def trade_push(
    # 公共参数
    sid: str = Form(...),
    appkey: str = Form(...),
    timestamp: int = Form(...),
    sign: str = Form(...),
    # 业务参数
    shop_no: str = Form(...),
    switch: Optional[int] = Form(1),
    trade_list: str = Form(...)  # JSON字符串格式
):
    """旺店通订单推送接口"""
    try:
        import json
        
        # 验证时间戳（5分钟内有效）
        current_time = int(time.time())
        if abs(current_time - timestamp) > 300:
            return {"code": 2001, "message": "timestamp无效"}
        
        # 解析trade_list JSON
        try:
            trade_list_data = json.loads(trade_list)
        except:
            return {"code": 2002, "message": "trade_list格式错误"}
        
        # 验证签名（这里需要配置app_secret）
        app_secret = "your_app_secret"  # 需要配置实际的app_secret
        params = {
            'sid': sid,
            'appkey': appkey,
            'timestamp': timestamp,
            'shop_no': shop_no,
            'switch': switch,
            'trade_list': trade_list
        }
        
        if not verify_signature(params.copy(), app_secret):
            return {"code": 2003, "message": "签名验证失败"}
        
        # 处理每个订单
        success_count = 0
        error_orders = []
        
        for trade_data in trade_list_data:
            try:
                # 检查订单是否已存在
                check_sql = "SELECT COUNT(*) as count FROM wangdian_orders WHERE tid = %s AND sid = %s"
                existing = read_query(check_sql, [trade_data['tid'], sid], True)
                
                if existing and existing[0]['count'] > 0:
                    continue  # 订单已存在，跳过
                
                # 插入主订单
                insert_order_sql = """
                    INSERT INTO wangdian_orders (
                        sid, appkey, shop_no, tid, trade_status, pay_status, delivery_term,
                        trade_time, pay_time, fenxiao_type, purchase_id, fenxiao_nick,
                        buyer_nick, buyer_email, pay_id, pay_account, pay_method,
                        receiver_name, receiver_province, receiver_city, receiver_district,
                        receiver_address, receiver_mobile, receiver_telno, receiver_zip,
                        logistics_type, invoice_kind, invoice_title, invoice_content,
                        remark_flag, buyer_message, seller_memo, seller_flag,
                        post_amount, cod_amount, ext_cod_fee, other_amount, paid,
                        id_card_type, id_card, is_auto_wms, wms_type, warehouse_no,
                        created_at
                    ) VALUES (
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()
                    )
                """
                
                order_params = [
                    sid, appkey, shop_no, trade_data['tid'], trade_data['trade_status'],
                    trade_data.get('pay_status'), trade_data['delivery_term'],
                    trade_data.get('trade_time'), trade_data['pay_time'],
                    trade_data.get('fenxiao_type'), trade_data.get('purchase_id'),
                    trade_data.get('fenxiao_nick'), trade_data['buyer_nick'],
                    trade_data.get('buyer_email'), trade_data.get('pay_id'),
                    trade_data.get('pay_account'), trade_data.get('pay_method', 1),
                    trade_data['receiver_name'], trade_data['receiver_province'],
                    trade_data['receiver_city'], trade_data['receiver_district'],
                    trade_data['receiver_address'], trade_data['receiver_mobile'],
                    trade_data.get('receiver_telno'), trade_data.get('receiver_zip'),
                    trade_data.get('logistics_type', -1), trade_data.get('invoice_kind', 0),
                    trade_data.get('invoice_title'), trade_data.get('invoice_content'),
                    trade_data.get('remark_flag', 0), trade_data.get('buyer_message'),
                    trade_data.get('seller_memo'), trade_data.get('seller_flag', 0),
                    trade_data['post_amount'], trade_data['cod_amount'],
                    trade_data['ext_cod_fee'], trade_data['other_amount'],
                    trade_data['paid'], trade_data.get('id_card_type', 0),
                    trade_data.get('id_card'), trade_data.get('is_auto_wms', 0),
                    trade_data.get('wms_type'), trade_data.get('warehouse_no')
                ]
                
                result = read_query(insert_order_sql, order_params, False)
                
                if not result:
                    error_orders.append(f"订单{trade_data['tid']}插入失败")
                    continue
                
                # 插入订单项
                for item in trade_data['order_list']:
                    insert_item_sql = """
                        INSERT INTO wangdian_order_items (
                            tid, oid, num, price, status, refund_status, goods_id, spec_id,
                            goods_no, spec_no, goods_name, spec_name, adjust_amount,
                            discount, share_discount, commission, remark, cid, created_at
                        ) VALUES (
                            %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW()
                        )
                    """
                    
                    item_params = [
                        trade_data['tid'], item['oid'], item['num'], item['price'],
                        item['status'], item['refund_status'], item['goods_id'],
                        item.get('spec_id'), item.get('goods_no'), item['spec_no'],
                        item['goods_name'], item.get('spec_name'), item['adjust_amount'],
                        item['discount'], item['share_discount'], item.get('commission', 0),
                        item.get('remark'), item.get('cid')
                    ]
                    
                    read_query(insert_item_sql, item_params, False)
                
                success_count += 1
                
            except Exception as e:
                error_orders.append(f"订单{trade_data.get('tid', 'unknown')}处理失败: {str(e)}")
        
        if error_orders:
            return {
                "code": 1001,
                "message": f"部分订单处理失败，成功{success_count}个",
                "errors": error_orders
            }
        
        return {
            "code": 0,
            "message": f"订单推送成功，共处理{success_count}个订单"
        }
        
    except Exception as e:
        return {"code": 1000, "message": f"系统错误: {str(e)}"}

@router.get("/order/{tid}")
async def get_order_detail(tid: str, sid: str):
    """获取订单详情"""
    try:
        # 获取主订单
        order_sql = "SELECT * FROM wangdian_orders WHERE tid = %s AND sid = %s"
        order = read_query(order_sql, [tid, sid], True)
        
        if not order:
            raise HTTPException(status_code=404, detail="订单不存在")
        
        # 获取订单项
        items_sql = "SELECT * FROM wangdian_order_items WHERE tid = %s"
        items = read_query(items_sql, [tid], True) or []
        
        return {
            "order": order[0],
            "items": items
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/orders")
async def get_order_list(
    sid: str,
    shop_no: Optional[str] = None,
    trade_status: Optional[int] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    page: int = 1,
    page_size: int = 20
):
    """获取订单列表"""
    try:
        conditions = ["sid = %s"]
        params = [sid]
        
        if shop_no:
            conditions.append("shop_no = %s")
            params.append(shop_no)
        if trade_status is not None:
            conditions.append("trade_status = %s")
            params.append(trade_status)
        if start_date:
            conditions.append("created_at >= %s")
            params.append(start_date)
        if end_date:
            conditions.append("created_at <= %s")
            params.append(end_date)

        where_clause = " AND ".join(conditions)
        
        # 计算总数
        count_sql = f"SELECT COUNT(*) as total FROM wangdian_orders WHERE {where_clause}"
        total_result = read_query(count_sql, params, True)
        total = total_result[0]['total'] if total_result else 0

        # 获取分页数据
        offset = (page - 1) * page_size
        orders_sql = f"""
            SELECT * FROM wangdian_orders 
            WHERE {where_clause}
            ORDER BY created_at DESC
            LIMIT %s OFFSET %s
        """
        
        params.extend([page_size, offset])
        orders = read_query(orders_sql, params, True) or []

        return {
            "total": total,
            "items": orders
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
